home *** CD-ROM | disk | FTP | other *** search
- #
- # this file contains trap handlers etc for gdb.
- # see atarist.c for things that call this.
- #
- # Format of a context block:
- # registers d0-d7 8 * 4
- # registers a0-a6 7 * 4
- # USP (.+60) 4
- # [SSP 4]
- # PC (.+64) 4
- # SR (.+68) 2
- # ------
- # totalling 70 bytes
-
- .data
- .comm _child_context,70
- .comm _dbg_context,70
- .comm _old_ipl_2_vector,4
- .globl _child_context
- .globl _dbg_context
-
- #
-
- .text | this is the replacement handler
- .globl _ipl_2_vector | for the IPL 2 interrupt.
- _ipl_2_vector: | it's used to catch child programs
- | when we spawn them
- movel _old_ipl_2_vector,0x68 | restore the IPL 2 vector
- movew d0,sp@- | get a temp
- movew sp@(2),d0 | get the saved SR
- andiw #0x0700,d0 | mask for current IPL
- beq L1 | 0? ok, that means we're spawning
- oriw #0x0300,sp@(2) | set ipl in saved SR to 3
- movew sp@+,d0 | get reg back
- rte
-
- L1:
- | we've just started a child program,
- | and have ended up here, via HBLANK,
- | before executing the first instruction
- | of the child.
- | Save the child context into the child
- | context block, restore the debugger
- | context from its context block, and
- | RTE into it.
- movew sp@+,d0 | get our d0 back
- moveml d0-a6,_child_context
- lea _child_context+15*4,a0
- movel usp,a1 | since this runs in super mode,
- movel a1,a0@+ | we get the USP this way
-
- # movel sp,a0@+ | that's the SSP
-
- movew sp@+,d0 | save the old SR
- movel sp@+,a0@+ | get the child PC
- andiw #0xF8FF,d0 | zap the IPL
- oriw #0x0300,d0 | and set to IPL 3
- movew d0,a0@+ | and finally save the SR
-
- tstw 0x59e:w |_longframe
- beq notlong1
- addql #2,sp | "pop" the frame word
- notlong1:
-
- #
- # now we have the child context safely stashed. Go run the
- # debugger context
- #
-
- jmp run_debugger
-
- #
- # this thing is for faking up a return context when we're
- # setting things up in the first place. This is really sort of gross.
- # we funcall this routine from debugger initialization, when we're about
- # ready to start the child program. We want to return to the place
- # that called this routine, so we can make like we returned after
- # starting the child. The way we do it is like this: Before starting
- # the child, somebody will setjmp to make a jump block. We then call
- # setup_fake_debugger_context with the jump block. It gets stashed here,
- # and we save the SP. We then stash our registers etc in the debugger
- # context block (though that's probly not strictly necessary) with the
- # PC of our fake_return kludge, below. When we actually decide to switch
- # context back to the debugger, we RTE to the return_kludge, which will
- # fake a call to longjmp with the context block. Yow.
- #
-
- .comm fake_return_jmpbuf,4
- .text
- .globl _setup_fake_debugger_context
- _setup_fake_debugger_context:
- moveml d0-a7,_dbg_context | a7 is usp, as this runs in user mode
- lea _dbg_context+15*4,a0
- subl #32,a0@+ | open a hole so that when we rte,
- | we'll have room
- movel #return_kludge,a0@+ | the place we will want to rte to
- movew #0x0300,d0 | SR: no T, no S, IPL 3
- movew d0,a0@+ | and our SR.
- #
- # now set up the funny return jmpbuf
- #
-
- movel sp@(4),fake_return_jmpbuf
- rts | and return!
-
- #
- # the thing we'll use when returning to debugger first time
- # after spawning child
- #
-
- .globl _longjmp
- return_kludge:
- pea 1:w | push a 1, to say we jumped
- movel fake_return_jmpbuf,sp@- | and the buf
- jsr _longjmp | and do the jump.
-
- #
- # exception handler entry points. We assume that these all happen from
- # the child program.
- #
-
- .comm _exception_number,4 | where we put what trap went off
- .globl _exception_2_vector
- _exception_2_vector:
- movel #2,_exception_number | bus error
- bra save_child
- .globl _exception_3_vector
- _exception_3_vector:
- movel #3,_exception_number | address error
- bra save_child
- .globl _exception_4_vector
- _exception_4_vector:
- movel #4,_exception_number | Illegal instr
- bra save_child
- .globl _exception_5_vector
- _exception_5_vector:
- movel #5,_exception_number | Zero dir
- bra save_child
- .globl _exception_6_vector
- _exception_6_vector:
- movel #6,_exception_number | CHK instr
- bra save_child
- .globl _exception_7_vector
- _exception_7_vector:
- movel #7,_exception_number | TRAPV
- bra save_child
- .globl _exception_8_vector
- _exception_8_vector:
- movel #8,_exception_number | priv
- bra save_child
- .globl _exception_9_vector
- _exception_9_vector:
- movel #9,_exception_number | trace
- bra save_child
-
- .globl _trap_f_vector
- _trap_f_vector:
- movel #10,_exception_number | breakpoint (trap #f)
- # bra save_child
-
- #
- # save the child context after some random trap
- #
-
- save_child:
- moveml d0-a6,_child_context
- lea _child_context+15*4,a0
- movel usp,a1 | since this runs in super mode,
- movel a1,a0@+ | we get the USP this way
-
- # movel sp,a0@+ | that's the SSP
- #
- # if this was an address error or bus error, there's 2 extra words of
- # stuff on the (system) stack.
- #
-
- tstw 0x59e:w |_longframe
- beq notlong2
-
- | new code to handle 680x0 frames, where x > 0
-
- .data
- ex_sizes: .byte 0, 0, 4, 0,0,0,0,0, 50, 12, 24, 84, 0,0,0,0
- .text
- movew sp@+,d0
- movel sp@+,a0@+
- movew d0,a0@+
-
- moveq #0,d0 | pre-clear d0
- movew sp@+,d0 | get frame word
- lsrw #8,d0 | shift into place
- lsrw #4,d0
- lea ex_sizes,a0
- moveb a0@(d0:w),d0 | d0 is now frame size
- addw d0,sp | pop the whole frame off
-
- bra long2done
-
- | old code to handle 68000 frames incl bus err & addr err
-
- notlong2:
- movel _exception_number,d0
- cmpl #2,d0
- beq save_child_1
- cmpl #3,d0
- bne save_child_2
- save_child_1:
- addql #8,sp | skip the extra cruft. later, maybe stash it
- | someplace? GDB apparently doesn't use this
- | info
- save_child_2:
- movew sp@+,d0 | save the old SR
- movel sp@+,a0@+ | get the child PC
- movew d0,a0@+ | and finally save the SR
-
- long2done:
-
- #
- # restore the debugger's context, and rte into it
- #
-
- run_debugger:
- movel _dbg_context+15*4,a0
- movel a0,usp
- moveml _dbg_context,d0-a6
- tstw 0x59e:w |_longframe
- beq notlong3
- clrw sp@-
- notlong3:
- movel _dbg_context+64,sp@-
- movew _dbg_context+68,sp@-
- rte | Poof!
-
- #
- # now for some real magic. After a trap, the way we get back into the
- # child context is by having our own trap vector for trap #0. Our
- # vector does a context switch!
- #
-
- .globl _trap_0_vector
- _trap_0_vector:
- #
- # save debugger context, so we can transfer back to
- # the child context
- #
-
- save_debugger:
- moveml d0-a6,_dbg_context
- lea _dbg_context+15*4,a0
- movel usp,a1 | since this runs in super mode,
- movel a1,a0@+ | we get the USP this way
-
- # movel sp,a0@+ | that's the SSP
-
- movew sp@+,d0 | save the old SR
- movel sp@+,a0@+ | get the child PC
- movew d0,a0@+ | and finally save the SR
- tstw 0x59e:w |_longframe
- beq notlong4
- addqw #2,sp | pop frame word off
- notlong4:
-
- #
- # Same deal, but run the child
- #
-
- run_child:
- movel _child_context+15*4,a0
- movel a0,usp
- moveml _child_context,d0-a6
- tstw 0x59e:w |_longframe
- beq notlong5
- clrw sp@-
- notlong5:
- movel _child_context+64,sp@-
- movew _child_context+68,sp@-
- rte | Poof!
-